const defaultData = {
  isShowCropper: false,
  // 初始化的宽高
  cropperInitW: 750,
  cropperInitH: 750,
  // 动态的宽高
  cropperW: 750,
  cropperH: 750,
  // 动态的left top值
  cropperL: 0,
  cropperT: 0,

  transL: 0,
  transT: 0,

  // 图片缩放值
  scaleP: 0,
  imageW: 0,
  imageH: 0,

  // 裁剪框 宽高
  cutL: 0,
  cutT: 0,
  cutB: 0,
  cutR: 0,

  qualityWidth: '',
  innerAspectRadio: 750 / wx.getSystemInfoSync().windowWidth,

  C_CONSTANTS: {
    SCREEN_WIDTH: 750,
    PAGE_X: 0, // 手按下的x位置
    PAGE_Y: 0, // 手按下y的位置
    PR: wx.getSystemInfoSync().pixelRatio, // dpi
    T_PAGE_X: {}, // 手移动的时候x的位置
    T_PAGE_Y: {}, // 手移动的时候Y的位置
    CUT_L: 0, // 初始化拖拽元素的left值
    CUT_T: 0, // 初始化拖拽元素的top值
    CUT_R: 0, // 初始化拖拽元素的
    CUT_B: 0, // 初始化拖拽元素的
    CUT_W: 0, // 初始化拖拽元素的宽度
    CUT_H: 0, //  初始化拖拽元素的高度
    IMG_RATIO: 0, // 图片比例
    IMG_REAL_W: 0, // 图片实际的宽度
    IMG_REAL_H: 0, // 图片实际的高度
    IMG_TYPE: '', //图片的格式
    DRAFG_MOVE_RATIO: 750 / wx.getSystemInfoSync().windowWidth //移动时候的比例
  }
};
let data = {};

try {
  data = JSON.parse(JSON.stringify(defaultData));
} catch (e) {
  console.log(e)
};

Component({
  properties: {
    imageSrc: {
      type: String,
      value: '',
      observer(newVal, oldVal) {
        if (newVal !== oldVal) {
          this.setData({
            isShowCropper: true
          }, () => {
            this.loadImage();
          })
        }

      }
    },
    isCircleCrop: {
      type: Boolean,
      value: false
    },
    enableScale: {
      type: Boolean,
      value: false
    },
    ratio: {
      type: Number,
      value: 1
    }
  },
  data,
  ready() {
    if (this.data.isCircleCrop) {
      //圆形裁剪 强制比例为1
      this.setData({
        ratio: 1
      })
    }
  },
  methods: {
    loadImage() {
      let {
        ratio,
        imageSrc
      } = this.data;
      let {
        IMG_REAL_W,
        IMG_REAL_H,
        IMG_RATIO,
        SCREEN_WIDTH,
        IMG_TYPE
      } = this.data.C_CONSTANTS;
      wx.getImageInfo({
        src: imageSrc,
        success: res => {
          IMG_REAL_W = res.width;
          IMG_REAL_H = res.height;
          IMG_RATIO = IMG_REAL_W / IMG_REAL_H;
          IMG_TYPE = res.type === 'png' ? 'png' : 'jpg';
          // 根据图片的宽高显示不同的效果   保证图片可以正常显示
          let temp = {};
          let cropperData = {};
          if (IMG_RATIO >= 1) {
            cropperData = {
              cropperW: SCREEN_WIDTH,
              cropperH: SCREEN_WIDTH / IMG_RATIO,
              // 初始化left right
              cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
              cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2)
            }
            if (ratio > 1) {
              temp = {
                cutL: (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2,
                cutT: (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / ratio) / 2,
                cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2 - SCREEN_WIDTH / IMG_RATIO,
                cutB: SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / ratio) / 2 - SCREEN_WIDTH / IMG_RATIO / ratio
              }
            } else {
              temp = {
                cutT: 0,
                cutB: 0,
                cutL: (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * ratio) / 2,
                cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * ratio) / 2 - SCREEN_WIDTH / IMG_RATIO * ratio
              }
            }
          } else {
            cropperData = {
              cropperW: SCREEN_WIDTH * IMG_RATIO,
              cropperH: SCREEN_WIDTH,
              // 初始化left right
              cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
              cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2)
            }
            if (ratio > 1) {
              temp = {
                cutL: 0,
                cutR: 0,
                cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / ratio) / 2,
                cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / ratio) / 2 - SCREEN_WIDTH * IMG_RATIO / ratio
              }
            } else {
              temp = {
                cutL: (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * ratio) / 2,
                cutR: SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * ratio) / 2 - SCREEN_WIDTH * IMG_RATIO * ratio,
                cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2,
                cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2 - SCREEN_WIDTH * IMG_RATIO
              }

            }
          }
          this.setData({
            C_CONSTANTS: Object.assign({}, this.data.C_CONSTANTS, {
              IMG_REAL_W,
              IMG_REAL_H,
              IMG_RATIO,
              IMG_TYPE
            }),
            isShowCropper: true,
            // 图片缩放值
            scaleP: IMG_REAL_W / SCREEN_WIDTH,
            qualityWidth: IMG_REAL_W,
            innerAspectRadio: IMG_RATIO,
            ...temp,
            ...cropperData
          })
        }
      });

    },
    contentStartMove(e) {
      this.setData({
        'C_CONSTANTS.PAGE_X': e.touches[0].pageX,
        'C_CONSTANTS.PAGE_Y': e.touches[0].pageY
      })
    },
    // 拖动时候触发的touchMove事件
    contentMoveing(e) {
      let {
        PAGE_X,
        PAGE_Y,
        DRAFG_MOVE_RATIO
      } = this.data.C_CONSTANTS;
      let {
        cutL,
        cutR,
        cutT,
        cutB
      } = this.data;
      let dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
      let dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
      // 左移
      if (dragLengthX > 0) {
        if (cutL - dragLengthX < 0) dragLengthX = cutL
      } else {
        if (cutR + dragLengthX < 0) dragLengthX = -cutR
      }

      if (dragLengthY > 0) {
        if (cutT - dragLengthY < 0) dragLengthY = cutT
      } else {
        if (cutB + dragLengthY < 0) dragLengthY = -cutB
      }
      this.setData({
        cutL: cutL - dragLengthX,
        cutT: cutT - dragLengthY,
        cutR: cutR + dragLengthX,
        cutB: cutB + dragLengthY,
        'C_CONSTANTS.PAGE_X': e.touches[0].pageX,
        'C_CONSTANTS.PAGE_Y': e.touches[0].pageY
      });
    },
    // 设置大小的时候触发的touchStart事件
    dragStart(e) {
      console.log(111)
      let {
        cutL,
        cutR,
        cutT,
        cutB
      } = this.data;
      // this.setData({
      //     C_CONSTANTS:Object.assign({},this.data.C_CONSTANTS,{
      //         T_PAGE_X : e.touches[0].pageX,
      //         T_PAGE_Y : e.touches[0].pageY,
      //         CUT_L : cutL,
      //         CUT_R : cutR,
      //         CUT_B : cutB,
      //         CUT_T : cutT
      //     })
      // })

    },
    // 设置大小的时候触发的touchMove事件
    dragMove(e) {
      let dragType = e.target.dataset.drag
      let {
        ratio,
        cropperW,
        cropperH,
        cutL,
        cutT,
        cutR,
        cutB,
        enableScale
      } = this.data;
      let {
        CUT_R,
        CUT_L,
        CUT_T,
        CUT_B,
        T_PAGE_X,
        T_PAGE_Y,
        DRAFG_MOVE_RATIO
      } = this.data.C_CONSTANTS;
      let dragLength;
      switch (dragType) {
        case 'right':
          dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
          if (CUT_R + dragLength < 0) dragLength = -CUT_R
          cutR = CUT_R + dragLength;
          if (enableScale) {
            cutT = CUT_T + dragLength / ratio;
          }
          if (cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;
          break;
        case 'left':
          dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
          if (CUT_L - dragLength < 0) dragLength = CUT_L
          if ((CUT_L - dragLength) > (this.data.cropperW - this.data.cutR)) dragLength = CUT_L - (this.data.cropperW - this.data.cutR)
          cutL = CUT_L - dragLength;
          if (enableScale) {
            cutT = CUT_T - dragLength / ratio;
          }
          if (cutL < 0 || cutT < 0 || cutT > cropperH || cutL > cropperW) return;
          break;
        case 'top':
          dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
          if (CUT_T - dragLength < 0) dragLength = CUT_T
          if ((CUT_T - dragLength) > (this.data.cropperH - this.data.cutB)) dragLength = CUT_T - (this.data.cropperH - this.data.cutB)
          cutT = CUT_T - dragLength;
          if (enableScale) {
            cutR = CUT_R - dragLength * ratio;
          }
          break;
        case 'bottom':
          dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
          if (CUT_B + dragLength < 0) dragLength = -CUT_B
          cutB = CUT_B + dragLength;
          if (enableScale) {
            cutR = CUT_R + dragLength * ratio;
          }
          if (cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;
          break;
        default:
          '';
      }
      this.setData({
        cutL,
        cutT,
        cutR,
        cutB
      });
    },
    contentTouchEnd() {},
    // 获取图片
    confirmCropper() {
      const {
        isCircleCrop
      } = this.data;;
      if (isCircleCrop) {
        this.circleCrop()
      } else {
        this.normalCropper();
      }
    },

    normalCropper() {
      let {
        imageSrc,
        cropperW,
        cropperH,
        cutL,
        cutT,
        cutR,
        cutB
      } = this.data;
      let {
        IMG_REAL_W,
        IMG_REAL_H,
        IMG_TYPE
      } = this.data.C_CONSTANTS;
      // 将图片写入画布
      const ctx = wx.createCanvasContext('cropper', this)
      ctx.drawImage(imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
      ctx.draw(true, () => {
        // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
        let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_W
        let canvasH = ((cropperH - cutT - cutB) / cropperH) * IMG_REAL_H
        let canvasL = (cutL / cropperW) * IMG_REAL_W
        let canvasT = (cutT / cropperH) * IMG_REAL_H
        wx.canvasToTempFilePath({
          x: canvasL,
          y: canvasT,
          width: canvasW,
          height: canvasH,
          destWidth: canvasW,
          destHeight: canvasH,
          fileType: IMG_TYPE || 'jpg',
          canvasId: 'cropper',
          success: (res) => {
            //图片裁剪成功
            this.cancelCropper();
            this.triggerEvent('cropperDone', {
              src: res.tempFilePath,
              cropperData: {
                x: canvasL,
                y: canvasT,
                width: canvasW,
                height: canvasH
              }
            })
          },
          fail: err => {
            this.triggerEvent('cropperFail', err)
          }
        }, this);
      })
    },

    circleCrop() {
      let {
        imageSrc,
        cropperW,
        cropperH,
        cutL,
        cutT,
        cutR,
        cutB
      } = this.data;
      let {
        IMG_REAL_W,
        IMG_REAL_H,
        IMG_TYPE
      } = this.data.C_CONSTANTS;
      // 将图片写入画布
      const ctx = wx.createCanvasContext('cropper', this)
      let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_W
      let canvasL = (cutL / cropperW) * IMG_REAL_W
      let canvasT = (cutT / cropperH) * IMG_REAL_H

      this.setData({
        canvasW: canvasW,
        canvasH: canvasW
      }, () => {
        ctx.arc(canvasW / 2, canvasW / 2, canvasW / 2, 0, 2 * Math.PI);
        ctx.clip();
        ctx.drawImage(imageSrc, canvasL, canvasT, canvasW, canvasW, 0, 0, canvasW, canvasW);
        ctx.draw(true, () => {
          wx.canvasToTempFilePath({
            fileType: IMG_TYPE || 'jpg',
            canvasId: 'cropper',
            success: (res) => {
              //图片裁剪成功
              this.cancelCropper();
              this.triggerEvent('cropperDone', {
                src: res.tempFilePath,
                cropperData: {
                  x: canvasL,
                  y: canvasT,
                  width: canvasW,
                  height: canvasW
                }
              })
            },
            fail: err => {
              this.triggerEvent('cropperFail', err)
            }
          }, this);
        })
      })
    },

    cancelCropper() {
      let originData = {}
      try {
        originData = JSON.parse(JSON.stringify(defaultData))
      } catch (e) {};

      this.setData({
        ...originData
      });
      this.triggerEvent('cropperCancel')
    }
  }
})